package com.data.modules.message.job;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.data.common.entity.CrmSiteResultSearchBO;
import com.data.common.util.DateUtils;
import com.data.config.JeBootMsgProperties;
import com.data.modules.feign.CrmService;
import com.data.modules.message.entity.SysMessage;
import com.data.modules.message.handle.ISendMsgHandle;
import com.data.modules.message.handle.enums.SendMsgStatusEnum;
import com.data.modules.message.handle.enums.SendMsgTypeEnum;
import com.data.modules.message.handle.executor.MessageExecutor;
import com.data.modules.message.handle.executor.MessageSend;
import com.data.modules.message.service.ISysMessageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * 发送消息任务
 */
@SuppressWarnings("ALL")
@Slf4j
public class SendAIMsgJob implements Job, MessageSend<SysMessage> {

    private static LinkedBlockingDeque queue;

    /**
     * 若参数变量名修改 QuartzJobController中也需对应修改
     */
    private String parameter;

    public void setParameter(String parameter) {
        this.parameter = parameter;
    }

    @Autowired
    private ISysMessageService messageService;

    @Autowired
    private JeBootMsgProperties msgProperties;
    @Autowired
    private CrmService crmService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info(String.format(" Data-Boot 发送AI消息任务 SendAIMsgJob !  时间:" + DateUtils.getTimestamp()));

        MessageExecutor.execute(this::bulidMessageBeforeSend, this);

    }

    public List<SysMessage> bulidMessageBeforeSend() {
        // 1.读取消息中心数据，只查询未发送的和发送失败不超过次数的
        List<SysMessage> list = messageService.lambdaQuery()
                .in(StringUtils.isNotBlank(parameter), SysMessage::getEsTitle, parameter.split(","))
                .eq(SysMessage::getEsType, msgProperties.getAi().getEsType())
                .in(SysMessage::getEsSendStatus, SendMsgStatusEnum.WAIT.getCode(), SendMsgStatusEnum.FAIL.getCode())
                .lt(SysMessage::getEsSendNum, 5)
                .orderByAsc(SysMessage::getEsSendStatus).orderByAsc(SysMessage::getEsSendNum).orderByAsc(SysMessage::getCreateTime)
                .page(new Page<>(1, msgProperties.getAi().getQueueCapacity())).getRecords()
                .stream().peek(this::encryCustomer).collect(Collectors.toList());
        log.info("==query sms msg count:{}", list.size());
        return list;
    }

    @Override
    public void afterSend(SysMessage message, Supplier<Boolean> sendResult) {
        if (sendResult.get()) {
            try {
                long timeout = msgProperties.getAi().getTimeout();
                log.info("sleep time ={}", timeout);
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                log.error("sleep 异常", e);
            }
        }

    }

    @Override
    public boolean send(SysMessage message) {

        SysMessage sysMessage = messageService.lambdaQuery().eq(SysMessage::getId, message.getId()).one();
        LambdaUpdateWrapper<SysMessage> wrapper = new LambdaUpdateWrapper<>();
        // 发送结果回写到数据库
        wrapper.eq(SysMessage::getId, message.getId());
        //默认发送失败 回调时更新为成功 未回调或回调失败则继续
        wrapper.set(SysMessage::getEsSendStatus, SendMsgStatusEnum.FAIL.getCode());
        try {
            ISendMsgHandle sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.AI.getImplClass()).newInstance();
            sendMsgHandle.sendMsg(message.getId(), message.getEsReceiver(), message.getEsTitle(),
                    message.getEsContent().toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            String msg = e.getMessage();
            if (msg.length() > 200) {
                msg = msg.substring(0, 200);
            }
            log.error(e.getMessage(), e);
            //消息未发送 直接下一条
            wrapper.set(SysMessage::getEsResult, msg);
            messageService.update(wrapper);
            return false;
        }
        Integer sendNum = message.getEsSendNum();
        wrapper.set(SysMessage::getEsSendNum, ++sendNum);
        wrapper.set(SysMessage::getEsResult, "默认发送失败");
        messageService.update(wrapper);

        if(++sendNum ==5){//超过5次 发送bp 通知
            CrmSiteResultSearchBO bo = new CrmSiteResultSearchBO();

            if(ObjectUtil.isNotEmpty(sysMessage)){
                String json = sysMessage.getEsParam();
                JSONObject object = JSONObject.parseObject(json);
                String name = object.getString("name");
                String ownerUserId = object.getString("ownerUserId");
                String mobile = object.getString("mobile");

                bo.setCustomerName(name);
                bo.setOwnerUserId(Integer.parseInt(ownerUserId));
                bo.setCustomerMobile(mobile);
                crmService.sendSms(bo);
            }
        }

        return true;
    }

    /**
     * 脱敏
     *
     * @param sysMessage
     */
    private void encryCustomer(SysMessage sysMessage) {

        if(ObjectUtil.equal(1,sysMessage.getType())){//加密处理
            //身份证脱敏
            if (sysMessage.getEsContent().contains("身份证:")) {
                String content = sysMessage.getEsContent();
                int i = content.indexOf("身份证: ");
                String idCard = content.substring(i + 5, i+23);
                String card = encryIdCard(idCard);
                content = content.replace(idCard, card);
                sysMessage.setEsContent(content);
                log.info("劳动者 json = {},身份证 replace={} ", JSONObject.toJSONString(sysMessage), card);
            }
            //电话号脱敏
            if (sysMessage.getEsContent().contains("电话:")) {
                String content = sysMessage.getEsContent().replaceAll("null","");

                int i = content.indexOf("电话:");
                String mobile = content.substring(i+4, i+15);
                String newMobile = encryMobile(mobile);
                content = content.replace(mobile, newMobile);
                sysMessage.setEsContent(content);
                log.info("劳动者 json = {},电话 replace={} ", JSONObject.toJSONString(sysMessage), newMobile);
            }
        }

    }

    /**
     * 脱敏 电话号
     *
     * @param mobile
     * @return
     */
    public static String encryMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return mobile;
        }
        return StrUtil.hide(mobile, 3, 7);
    }

    /**
     * 脱敏 身份证
     *
     * @param idcard
     * @return
     */
    public static String encryIdCard(String idcard) {
        if (StringUtils.isBlank(idcard)) {
            return idcard;
        }
        return StrUtil.hide(idcard, 6, 16);
    }

}
